package com.stars.easyms.swagger.plugin;

import com.google.common.base.Optional;
import com.google.common.collect.Sets;
import com.stars.easyms.rest.annotation.EasyMsRestController;
import org.apache.commons.lang3.reflect.FieldUtils;
import springfox.documentation.builders.ApiListingBuilder;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.ApiListingBuilderPlugin;
import springfox.documentation.spi.service.contexts.ApiListingContext;

import java.lang.reflect.Field;
import java.util.Set;

import static com.google.common.base.Optional.fromNullable;
import static com.google.common.collect.FluentIterable.from;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newTreeSet;
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
import static springfox.documentation.service.Tags.emptyTags;
import static springfox.documentation.swagger.common.SwaggerPluginSupport.pluginDoesApply;

/**
 * <p>className: EasyMsSwaggerApiListingReader</p>
 * <p>description: 设置swagger上api监控类</p>
 *
 * @author guoguifang
 * @version 1.2.1
 * @date 2019-07-04 17:36
 */
public final class EasyMsSwaggerApiListingReader implements ApiListingBuilderPlugin {

    @Override
    @SuppressWarnings("unchecked")
    public void apply(ApiListingContext apiListingContext) {
        com.google.common.base.Optional<? extends Class<?>> controller = apiListingContext.getResourceGroup().getControllerClass();
        if (controller.isPresent()) {
            Optional<EasyMsRestController> apiAnnotation = fromNullable(findAnnotation(controller.get(), EasyMsRestController.class));
            Set<String> tagSet = apiAnnotation.transform(input -> newTreeSet(from(newArrayList(input.name())).filter(emptyTags()).toSet())).or(Sets.newTreeSet());
            if (tagSet.isEmpty()) {
                tagSet.add(apiListingContext.getResourceGroup().getGroupName());
            }
            ApiListingBuilder apiListingBuilder = apiListingContext.apiListingBuilder();
            Field field = FieldUtils.getDeclaredField(ApiListingBuilder.class, "tagNames", true);
            if (field != null) {
                try {
                    Set<String> tagNames = (Set<String>) field.get(apiListingBuilder);
                    tagNames.clear();
                } catch (IllegalAccessException e) {
                    // ignore
                }
            }
            apiListingBuilder.tagNames(tagSet);
        }
    }

    @Override
    public boolean supports(DocumentationType delimiter) {
        return pluginDoesApply(delimiter);
    }
}